AddCSLuaFile("cl_init.lua")
AddCSLuaFile("shared.lua")
include("shared.lua")

function ENT:Initialize()
	self.Entity:PhysicsInit(SOLID_VPHYSICS)
	self.Entity:SetMoveType(MOVETYPE_VPHYSICS)
	self.Entity:SetCollisionGroup(COLLISION_GROUP_PROJECTILE)
	self.Entity:DrawShadow(false)
	self.Entity:SetGravity(0)
	
	self.Entity.Clear = false
	self.Entity.ClearTime = CurTime()
	
	self.Entity.Exists = true

	local physobj = self.Entity:GetPhysicsObject()
	physobj:SetDamping(0, 0)
	physobj:SetMass(1)
	physobj:EnableGravity(false)
	physobj:EnableDrag(false)
	physobj:SetBuoyancyRatio(0)
	
	self.Entity.CDamage = self.Entity.CDamage or {}
	self.Entity.CDamage.type = "torpedo"
	self.Entity.CDamage.maxhealth = 10
	self.Entity.CDamage.health = 10
	
	if (!(self.Entity.IsSubmunition or false)) then
		local netcolorvector = Vector(self.Entity.Color.r, self.Entity.Color.g, self.Entity.Color.b)
		self.Entity:SetNetworkedVector("color", netcolorvector)
		self.Entity:SetNetworkedString("damagetype", self.Entity.DamageType)
	end
	
	self.Entity:SetNetworkedBool("Drawmodel", true)
	self:StartMotionController()
	self.Entity:NextThink(CurTime() + 0.1)
end

function ENT:PhysicsCollide(data, physobj)
	self.Entity:GetPhysicsObject():SetVelocity(Vector(0,0,0))
	if util.tobool(self.Entity.BlastRadius) then
		timer.Simple(0.01, CDamage_blastdamage, self.Entity:GetPos(), self.Entity.BlastRadius, self.Entity.Damage, nil, false, self.Entity.DamageType)
	end
	timer.Simple(0.01, CDamage_damageent, data.HitEntity, self.Entity.Damage, nil, self.Entity.DamageType)
	self.Entity:DrawImpact()
	self.Entity:Desolidify()
end

function ENT:ImpactShield(shield)
	if (self.Entity.Damage > shield:GetHP()) then
		self.Entity.Damage = self.Entity.Damage - shield:GetHP()
		CDamage_damageent(shield, shield:GetHP(), nil, self.Entity.DamageType)
		self.Entity:DrawImpact(shield)
	else
		CDamage_damageent(shield, self.Entity.Damage, nil, self.Entity.DamageType)
		self.Entity:DrawImpact(shield)
		self.Entity:Desolidify()
	end
end

function ENT:Think()
	if self.Entity.Clear then
		self.Entity.speed = math.Clamp(((CurTime() - self.ClearTime) / self.Entity.acceltime) * self.Entity.maxspeed, self.Entity.minspeed, self.Entity.maxspeed)
	end
	if util.tobool(self.Entity:WaterLevel()) then
		self.Entity:SetGravity(0)
		self.Entity:GetPhysicsObject():EnableGravity(false)
		if !self.Entity.Clear then
			self.Entity.Clear = true
			self.Entity.ClearTime = CurTime()
		end
	else
		self.Entity.Clear = false
		self.Entity:SetGravity(1)
		self.Entity:GetPhysicsObject():EnableGravity(true)
	end
	self.Entity:NextThink(CurTime() + 0.1)
	return true
end

function ENT:PhysicsSimulate(phys, deltatime)
	local maxspeed
	local prevvelocity = self.Entity.prevvel or Vector(0,0,0)
	if (util.tobool(self.Entity:WaterLevel()) and self.Entity.Clear) then
		local curvel, destvel = prevvelocity, self.Entity:GetForward() * math.Clamp(self.Entity.speed, 0, self.Entity.maxspeed)
		local tfraction = math.Clamp((CurTime() - self.ClearTime) / self.Entity.acceltime, 0, 1)
		local cvelbias, destvelbias = (1 - tfraction), tfraction
		phys:SetVelocity((curvel * cvelbias) + (destvel * destvelbias))
		maxspeed = ((4000 * cvelbias) + (self.Entity.speed * destvelbias))
	elseif not util.tobool(self.Entity:WaterLevel()) then
		phys:SetVelocity(prevvelocity + (Vector(0, 0, -600) * deltatime))
		maxspeed = 4000
	end
	
	local velocitymove = self.Entity:GetPos() + phys:GetVelocity()
	self.Entity.prevvel = phys:GetVelocity()
	local resangle
	

	
	if util.tobool(self.Entity:WaterLevel()) then
		if ((self.Entity.Target != nil) and (self.Entity.Target:IsValid()) and (util.tobool(self.Entity.Target:WaterLevel())) and (self.speed > (self.Entity.maxspeed / self.Entity.acceltime))) then
			resangle = (self.Entity.Target:GetPos() - self.Entity:GetPos()):Angle()
		else
			resangle = self.Entity:GetForward():Angle()
		end
	elseif self.Entity.Clear then
		resangle = self.Entity:GetForward():Angle()
		resangle.p = 90
	else 
		resangle = self.Entity:GetForward():Angle()
	end
	
 	self.ShadowParams = {}  	
	self.ShadowParams.secondstoarrive = 1
	self.ShadowParams.pos = velocitymove
	self.ShadowParams.angle = resangle
	self.ShadowParams.maxangular = 5000
	self.ShadowParams.maxangulardamp = 5000
	self.ShadowParams.maxspeed = maxspeed
	self.ShadowParams.maxspeeddamp = maxspeed
	self.ShadowParams.dampfactor = 0.15 
	self.ShadowParams.teleportdistance = 0
	self.ShadowParams.deltatime = deltatime
	
	phys:ComputeShadowControl(self.ShadowParams)
end

--THIS FUNCTION IS INCREDIBLY BUGGY!
--[[ function ENT:PhysicsUpdate(phys)
	local processangles = false
	if (util.tobool(self.Entity:WaterLevel()) and self.Entity.Clear) then
		local curvel, destvel = phys:GetVelocity(), self.Entity:GetForward() * math.Clamp(self.Entity.speed, 0, self.Entity.maxspeed)
		local tfraction = math.Clamp((CurTime() - self.ClearTime) / self.Entity.acceltime, 0, 1)
		local cvelbias, destvelbias = (1 - tfraction), tfraction
		phys:SetVelocity((curvel * cvelbias) + (destvel * destvelbias))
		
		if ((self.Entity.Target != nil) and (self.Entity.Target:IsValid()) and (self.speed > (self.Entity.maxspeed / self.Entity.acceltime))) then
			resangle = (self.Entity.Target:GetPos() - self.Entity:GetPos()):Angle()
		else
			resangle = self.Entity:GetForward():Angle()
		end
		processangles = true
	elseif self.Entity.Clear then
		resangle = self.Entity:GetForward():Angle()
		resangle.p = 1
		processangles = true
	end 	
	if	processangles then
		--local destangle = (resangle - self.Entity:GetForward():Angle())
		local destangle = (resangle:Forward():Rotate(self.Entity:GetForward():Angle())):Angle()
		--destangle:Rotate(-1*self.Entity:GetForward())
		
		--ROLL, PITCH, YAW
		--DONT ASK! FOR THE LOVE OF GOD DON'T ASK!
		local processedangle = Vector(destangle.r, destangle.p, destangle.y)
		
		phys:AddAngleVelocity((-1 * (phys:GetAngleVelocity())) + processedangle)
	end
end ]]

function ENT:Desolidify()
	self.Entity.Exists = false
	self.Entity.speed = 0
	self.Entity:SetMoveType(MOVETYPE_NONE)
	self.Entity:SetCollisionGroup(COLLISION_GROUP_DEBRIS)
	self.Entity:SetNotSolid(true)
	self.Entity:SetNetworkedBool("Drawmodel", false)
	self.Entity.CDamage.type = "immune"
	timer.Simple(3, function() if self.Entity:IsValid() then self.Entity:Remove() end end)
end